<script setup>
  /**
   * 动态刻度可视化组件
   * width                           组件宽度：单位px
   * maxHeight                       刻度线最大高度：单位px
   * tickerBarSize                   tickerBar大小：单位px
   * tickerBarBorderWidth            tickerBar边框大小：单位px
   * tickerBarBorderStyle            tickerBar边框样式
   * tickerBarBorderColor            tickerBar边框颜色
   * tickerLineSize                  刻度线大小：单位px
   * tickerLineBorderWidth           刻度线边框大小：单位px
   * tickerLineBorderStyle           刻度线边框样式
   * tickerLineBorderColor           刻度线边框颜色
   * percent                         刻度线边框颜色
   * lineNum                         刻度线数量
   * defaultColor                    未激活时的颜色
   * activeColor                     激活时的颜色
   * value                           显示的值
   * unit                            显示的值的单位
   * valueStyle                      显示的值的样式
   * text                            显示的文本
   * textStyle                       显示的文本的样式
   */
  import { ref, computed, onMounted } from 'vue'

  const props = defineProps({
    width: { type: [String, Number], default: '100%' },
    maxHeight: { type: [String, Number], default: '100px' },
    tickerBarSize: { type: [String, Number], default: '7px' },
    tickerBarBorderWidth: { type: [String, Number], default: '1px' },
    tickerBarBorderStyle: { type: String, default: 'solid' },
    tickerBarBorderColor: { type: String, default: '#aaa' },
    tickerLineSize: { type: [String, Number], default: '7px' },
    tickerLineBorderWidth: { type: [String, Number], default: '1px' },
    tickerLineBorderStyle: { type: String, default: 'solid' },
    tickerLineBorderColor: { type: String, default: '#aaa' },
    percent: { type: [String, Number], default: 50 },
    lineNum: { type: Number, default: 10 },
    defaultColor: { type: String, default: 'transparent' },
    activeColor: { type: String, default: '#f00' },
    value: { type: [String, Number], default: '' },
    unit: { type: String, default: '' },
    valueStyle: { type: Object, default: () => {} },
    text: { type: String, default: '' },
    textStyle: { type: Object, default: () => {} },
  })

  const tickerComponentContainerRef = ref(null)

  // 刻度线之间的间隔(%)
  const gapPercent = computed(() => {
    let tickerLinePercent = 0
    if (tickerComponentContainerRef.value) {
      let compWidth = window.getComputedStyle(tickerComponentContainerRef.value, null).width
      tickerLinePercent = parseFloat(props.tickerLineSize) / parseFloat(compWidth) * 100
    }
    return (100 - tickerLinePercent) / (props.lineNum - 1)
  })

  // 刻度线高度数组
  const tickerLineArr = ref([])

  // 生成随机数
  const generateRandom = function() {
    let randomNum = Math.random() * parseFloat(props.maxHeight)
    let percent = 0.1
    let minNumber = parseFloat(props.maxHeight) * percent
    let maxNumber = parseFloat(props.maxHeight) - parseFloat(props.tickerBarSize)
    let result = randomNum
    if (result < minNumber) result = minNumber
    if (result >= maxNumber) result = maxNumber
    return result
  }

  // 填充刻度线高度数组
  const fillTickerLine = function() {
    tickerLineArr.value = []
    for (let i = 0; i < props.lineNum; i++) {
      tickerLineArr.value.push(generateRandom())
    }
  }

  fillTickerLine()
</script>

<template>
  <div
    ref="tickerComponentContainerRef"
    class="ticker-component-container"
    :style="{
      width: isNaN(Number(width)) ? width : width + 'px',
    }"
  >
    <div class="value-box">
      <span :style="valueStyle">{{ value }} {{ unit }}</span>
    </div>
    <div
      class="ticker-graph"
      :style="{
        height: parseFloat(maxHeight) + 'px',
      }"
    >
      <div
        class="ticker-line"
        v-for="index in lineNum"
        :key="index"
        :style="{
          width: parseFloat(tickerLineSize) + 'px',
          height: tickerLineArr[index - 1] + 'px',
          borderWidth: parseFloat(tickerLineBorderWidth) + 'px',
          borderStyle: tickerLineBorderStyle,
          borderColor: parseFloat(lineNum) * parseFloat(percent) / 100 >= index ? activeColor : tickerLineBorderColor,
          left: `calc(${(index - 1) * gapPercent}%)`,
          bottom: (parseFloat(tickerBarSize) - parseFloat(tickerBarBorderWidth)) + 'px',
          background: parseFloat(lineNum) * parseFloat(percent) / 100 >= index ? activeColor : defaultColor
        }"
      ></div>
      <div
        class="ticker-bar"
        :style="{
          height: parseFloat(tickerBarSize) + 'px',
          borderWidth: parseFloat(tickerBarBorderWidth) + 'px',
          borderStyle: tickerBarBorderStyle,
          borderColor: tickerBarBorderColor,
        }"
      ></div>
      <div
        class="active-bar"
        :style="{ 
          width: parseFloat(percent) + '%',
          height: parseFloat(tickerBarSize) + 'px',
          background: activeColor
        }"
      ></div>
    </div>
    <div class="text-box">
      <span :style="textStyle">{{ text }}</span>
    </div>
  </div>
</template>

<style scoped>
  .ticker-component-container {
  }
  .ticker-component-container .value-box {
    text-align: center;
  }
  .ticker-component-container .ticker-graph {
    margin: 20px 0;
    position: relative;
  }
  .ticker-component-container .ticker-graph .ticker-line {
    position: absolute;
    box-sizing: border-box;
  }
  .ticker-component-container .ticker-graph .ticker-bar {
    width: 100%;
    position: absolute;
    bottom: 0;
    box-sizing: border-box;
  }
  .ticker-component-container .ticker-graph .active-bar {
    position: absolute;
    bottom: 0;
  }
  .ticker-component-container .text-box {
    text-align: center;
  }
</style>
